package edu.gatech.cs4400.spring2014.A8.model;

import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Time;
import java.util.ArrayList;

import edu.gatech.cs4400.spring2014.A8.control.Session;
import edu.gatech.cs4400.spring2014.A8.view.Availability;

public class DoctorData {
	public static final String LICENSENO = "License No";
	public static final String FIRSTNAME = "First Name";
	public static final String LASTNAME = "Last Name";
	public static final String WORKPHONE = "Work Phone";
	public static final String SPECIALTY = "Specialty";
	public static final String HOMEADDR = "Home Address";
	public static final String DOB = "Date of Birth";
	public static final String ROOMNO = "Room Number";
	public static final String[] FIELD_NAMES = {LICENSENO, FIRSTNAME, LASTNAME, WORKPHONE, SPECIALTY, HOMEADDR, DOB, ROOMNO};
	
	private String licenseNo;
	private String firstName;
	private String lastName;
	private String workPhone;
	private String specialty;
	private String homeAddress;
	private Date dateOfBirth;
	private int roomNo;
	private ArrayList<Availability> availabilities;
	
	private boolean hasData;
	
	public DoctorData() {
		hasData = false;
		availabilities = new ArrayList<Availability>();
	}
	
	private String nullCheck(String text) {
		if (text == null) {
			return "";
		}
		return text;
	}
	
	public String getLicenseNo() 						{ return nullCheck(licenseNo);}
	public String getFirstName() 						{ return nullCheck(firstName);}
	public String getLastName() 						{ return nullCheck(lastName);}
	public String getWorkPhone() 						{ return nullCheck(workPhone);}
	public String getSpecialty() 						{ return nullCheck(specialty);}
	public String getHomeAddress() 						{ return nullCheck(homeAddress);}
	public Date getDateOfBirth() 						{ if (dateOfBirth != null) return (Date)dateOfBirth.clone(); return null;}
	public int getRoomNo() 								{ return roomNo;}
	@SuppressWarnings("unchecked")
	public ArrayList<Availability> getAvailability()	{ return (ArrayList<Availability>)availabilities.clone();}


	public void setLicenseNo(String data) 					 {licenseNo = nullCheck(data); }
	public void setFirstName(String data) 					 {firstName = nullCheck(data); }
	public void setLastName(String data) 					 {lastName = nullCheck(data); }
	public void setWorkPhone(String data) {
		data = nullCheck(data); 
		workPhone = DataCleaner.phoneNumber(data);
	}
	public void setSpecialty(String data) 					 {specialty = nullCheck(data); }
	public void setHomeAddress(String data) 				 {homeAddress = nullCheck(data); }
	public void setDateOfBirth(String data) 				 {dateOfBirth = DataCleaner.date(data); }
	public void setRoomNo(String data) 						 {roomNo = DataCleaner.nonnegativeInt(data); }
	public void setAvailabilty(ArrayList<Availability> data) { availabilities = data;}
	
	public String toString() {
		return String.format("%s %s %s %s %s %s %s %d", licenseNo, firstName, lastName, workPhone, specialty, homeAddress, dateOfBirth, roomNo);
	}
	
	public boolean loadData() {
		LoadAvailabilityQuery laq = new LoadAvailabilityQuery();
		laq.loadData();
		LoadDoctorDataQuery lddq = new LoadDoctorDataQuery();
		return lddq.loadData();
	}
	
	public boolean saveData() {
		SaveAvailabilityQuery saq = new SaveAvailabilityQuery();
		saq.saveData();
		SaveDoctorDataQuery sddq = new SaveDoctorDataQuery();
		return sddq.saveData();
	}
	
	private class LoadDoctorDataQuery extends ReadQuery {

		public LoadDoctorDataQuery() {
			sql = String.format("SELECT LicenseNo, FirstName, LastName, DateOfBirth, WorkPhone, Specialty, RoomNo, HomeAddress FROM Doctor WHERE Username='%s';", Session.getUsername());
		}
		
		@Override
		protected void parseResult(ResultSet rs) throws SQLException {
			if(rs.next()) {
				licenseNo = rs.getString("LicenseNo");
				firstName = rs.getString("FirstName");
				lastName = rs.getString("LastName");
				workPhone = rs.getString("WorkPhone");
				specialty = rs.getString("Specialty");
				homeAddress = rs.getString("HomeAddress");
				dateOfBirth = rs.getDate("DateOfBirth");
				roomNo = rs.getInt("RoomNo");
				
				hasData = true;
			}
		}
		
		public boolean loadData() {
			return execute();
		}
		
	}
	
	private class SaveDoctorDataQuery extends WriteQuery {
		
		public SaveDoctorDataQuery() {
			if (hasData) {
				sql = String.format("UPDATE Doctor SET LicenseNo='%s', " +
									"FirstName='%s', LastName='%s', WorkPhone='%s', " + 
									"Specialty='%s', HomeAddress='%s', DateOfBirth='%s', " +
									"RoomNo='%d' WHERE Username='%s';", getLicenseNo(), 
								    getFirstName(), getLastName(), getWorkPhone(), getSpecialty(),
								    getHomeAddress(), getDateOfBirth(), getRoomNo(), Session.getUsername());
			}
			else {
				sql = String.format("INSERT INTO Doctor(Username, LicenseNo, FirstName, " +
								    "LastName, WorkPhone, Specialty, HomeAddress, " +
								    "DateOfBirth, RoomNo) " +
								    "VALUES('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d);", Session.getUsername(), getLicenseNo(), 
								    getFirstName(), getLastName(), getWorkPhone(), getSpecialty(),
								    getHomeAddress(), getDateOfBirth(), getRoomNo());
			}
		}
		
		public boolean saveData() {
			return execute();
		}
	}
	
	private class LoadAvailabilityQuery extends ReadQuery {

		public LoadAvailabilityQuery() {
			sql = String.format("SELECT ToTime, FromTime, Day FROM Availability WHERE Doctor_Username='%s';", Session.getUsername());
		}
		
		@Override
		protected void parseResult(ResultSet rs) throws SQLException {
			while (rs.next()) {
				String day = rs.getString("Day");
				Time from = rs.getTime("FromTime");
				Time to = rs.getTime("ToTime");
				availabilities.add(new Availability(from, to, day));
			}
		}
		
		public boolean loadData() {
			return execute();
		}
	}
	
	private class SaveAvailabilityQuery extends WriteQuery {
		
		public boolean saveData() {
			sql = String.format("DELETE FROM Availability WHERE Doctor_Username='%s';\n", Session.getUsername());
			execute();
			reset();
			
			for (Availability avail : availabilities) {
				sql = String.format("INSERT INTO Availability(Doctor_Username, FromTime, ToTime, Day) " +
									 "VALUES('%s', '%s', '%s', '%s');\n", Session.getUsername(), avail.getFrom(), avail.getTo(), avail.getDay());
				execute();
				reset();
			}
			return true;
		}
	}
}
